﻿#ifndef __SS_SET_H__
#define __SS_SET_H__
#include "rbTree/ssRBTree.h"

namespace StarSeeker
{

template<typename SET_KEY, typename SET_POOL=ssDefMallocObject<ssRBTreeNode<SET_KEY> > >
class ssSet
{
public:
	class Iterator
	{
		friend class ssSet;
	public:
		Iterator() :m_pNode(0)
		{
		}
		Iterator(const Iterator & it) :m_pNode(it.m_pNode)
		{
		}
		Iterator(ssRBTreeNode<SET_KEY>* p) :m_pNode(p)
		{
		}
		bool operator == (const Iterator& it) const
		{
			return this->m_pNode == it.m_pNode;
		}
		bool operator != (const Iterator& it) const
		{
			return this->m_pNode != it.m_pNode;
		}
		void operator = (const Iterator & it)
		{
			this->m_pNode = it.m_pNode;
		}
		void operator ++ ()
		{
			ssRBTree<SET_KEY,SET_POOL>* pTree = (ssRBTree<SET_KEY,SET_POOL>*)m_pNode->Onwer();
			m_pNode = pTree->Next();
		}
		const SET_KEY& operator* ()
		{
			return m_pNode->GetKey();
		}
		const SET_KEY* Data()
		{
			if (m_pNode)
			{
				return &m_pNode->GetKey();
			}
			return 0;
		}
		bool IsVaild() const
		{
			if (!m_pNode)
			{
				return false;
			}
			if (0 == m_pNode->Onwer())
			{
				return false;
			}
			return true;
		}
	private:
		ssRBTreeNode<SET_KEY>*	m_pNode;
	};

	ssSet();
	error_t			Insert(const SET_KEY& k);
	Iterator		Find(const SET_KEY& k);
	error_t			Erase(Iterator & itr);
	error_t			Erase(const SET_KEY& k);
	Iterator		Begin();
	Iterator		End();
	void			Empty();
	ulint			Size();
	bool			Check();
	error_t			Error();
private:
	ssRBTree<SET_KEY,SET_POOL>	m_tree;
	error_t						m_errno;
};

template<typename SET_KEY,typename SET_POOL>
ssSet<SET_KEY,SET_POOL>::ssSet()
{
	m_errno = 0;
}

template<typename SET_KEY,typename SET_POOL>
inline error_t ssSet<SET_KEY,SET_POOL>::Insert(const SET_KEY& k)
{
	ssPair<ssRBTreeNode<SET_KEY>*, error_t> ret = m_tree.Insert(k);
	m_errno = ret.second;
	return ret.second;
}

template<typename SET_KEY,typename SET_POOL>
inline typename ssSet<SET_KEY,SET_POOL>::Iterator ssSet<SET_KEY,SET_POOL>::Find(const SET_KEY& k)
{
	ssRBTreeNode<SET_KEY>* ret = m_tree.Find(k);
	return ret;
}

template<typename SET_KEY,typename SET_POOL>
inline error_t ssSet<SET_KEY,SET_POOL>::Erase(Iterator & itr)
{
	m_errno = m_tree.Remove(itr.m_pNode);
	return m_errno;
}

template<typename SET_KEY,typename SET_POOL>
inline error_t ssSet<SET_KEY,SET_POOL>::Erase(const SET_KEY& k)
{
	m_errno = m_tree.Remove(k);
	return m_errno;
}

template<typename SET_KEY,typename SET_POOL>
inline typename ssSet<SET_KEY,SET_POOL>::Iterator StarSeeker::ssSet<SET_KEY,SET_POOL>::Begin()
{
	return m_tree.Begin();
}

template<typename SET_KEY,typename SET_POOL>
inline typename ssSet<SET_KEY,SET_POOL>::Iterator StarSeeker::ssSet<SET_KEY,SET_POOL>::End()
{
	return m_tree.End();
}

template<typename SET_KEY,typename SET_POOL>
void StarSeeker::ssSet<SET_KEY,SET_POOL>::Empty()
{
	m_tree.Empty();
}

template<typename SET_KEY,typename SET_POOL>
ulint StarSeeker::ssSet<SET_KEY,SET_POOL>::Size()
{
	return m_tree.GetCount();
}

template<typename SET_KEY,typename SET_POOL>
bool StarSeeker::ssSet<SET_KEY,SET_POOL>::Check()
{
	return m_tree.Check();
}

template<typename SET_KEY, typename SET_POOL>
error_t StarSeeker::ssSet<SET_KEY, SET_POOL>::Error()
{
	return m_errno;
}

#define SS_SET_O(SET_KEY) StarSeeker::ssSet<SET_KEY, StarSeeker::ssMallocObj<StarSeeker::ssRBTreeNode<SET_KEY> > >
#define SS_SET_N(SET_KEY) StarSeeker::ssSet<SET_KEY, StarSeeker::ssMalloc<sizeof(StarSeeker::ssRBTreeNode<SET_KEY>) > >
}
#endif
